﻿using ETW.EventListeners.Listeners;
using ETW.EventListeners.ObjectValues;
using System;
using System.Diagnostics.Tracing;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleLog
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var listener = new RuntimeEventListener())
            {
                listener.OnActiveTimerCountWritten += LogMeanCounterPayload;
                listener.OnAllocRateWritten += LogSumCounterPayload;
                listener.OnAssemblyCountWritten += LogMeanCounterPayload;
                listener.OnCpuUsageWritten += LogMeanCounterPayload;
                listener.OnExceptionCountWritten += LogSumCounterPayload;
                listener.OnGcCommittedBytesWritten += LogSumCounterPayload;
                listener.OnGcFragmentationWritten += LogMeanCounterPayload;
                listener.OnGCHeapSizeWritten += LogMeanCounterPayload;
                listener.OnGen0GcCountWritten += LogSumCounterPayload;
                listener.OnGen0GcSizeWritten += LogMeanCounterPayload;
                listener.OnGen1GcCountWritten += LogSumCounterPayload;
                listener.OnGen1GcSizeWritten += LogMeanCounterPayload;
                listener.OnGen2GcCountWritten += LogSumCounterPayload;
                listener.OnGen2GcSizeWritten += LogMeanCounterPayload;
                listener.OnILBytesJittedWritten += LogMeanCounterPayload;
                listener.OnLOHSizeWritten += LogMeanCounterPayload;
                listener.OnMethodJittedCountWritten += LogMeanCounterPayload;
                listener.OnMonitorLockContentionCountWritten += LogSumCounterPayload;
                listener.OnPOHSizeWritten += LogMeanCounterPayload;
                listener.OnThreadPoolCompletedTimesCountWritten += LogSumCounterPayload;
                listener.OnThreadPoolQueueLengthWritten += LogMeanCounterPayload;
                listener.OnThreadPoolThreadCountWritten += LogMeanCounterPayload;
                listener.OnTimeInGcWritten += LogMeanCounterPayload;
                listener.OnWorkingSetWritten += LogMeanCounterPayload;

                Task.Factory.StartNew(() => {
                    Thread.Sleep(TimeSpan.FromSeconds(2));
                });
                Task.Factory.StartNew(() => {
                    var bytes = new byte[1024];
                    Thread.Sleep(TimeSpan.FromSeconds(4));
                });
                Task.Factory.StartNew(() => {
                    var bytes = new byte[1024];
                    Thread.Sleep(TimeSpan.FromSeconds(6));
                });
                Task.Factory.StartNew(() => {
                    Thread.Sleep(TimeSpan.FromSeconds(8));
                });

                Console.WriteLine(ThreadPool.ThreadCount);

                Console.ReadLine();
            }
        }

        /***
        private static void Listener_OnWritten(ETW.EventListeners.Entities.RuntimeEntity obj)
        {
            Console.WriteLine();
            Console.WriteLine($"==================begin={DateTime.Now}==================");

            Console.WriteLine("自上次 GC 以来 GC 的时间百分比:");
            LogMeanCounterPayload(obj.TimeInGc);
            Console.WriteLine();

            Console.WriteLine("每个更新间隔分配的字节数:");
            LogSumCounterPayload(obj.AllocRate);
            Console.WriteLine();

            Console.WriteLine("相对于所有系统 CPU 资源进程的 CPU 使用率百分比:");
            LogMeanCounterPayload(obj.CpuUsage);
            Console.WriteLine();

            Console.WriteLine("已发生的异常数:");
            LogSumCounterPayload(obj.ExceptionCount);
            Console.WriteLine();

            Console.WriteLine("认为要分配的字节数:");
            LogMeanCounterPayload(obj.GCHeapSize);
            Console.WriteLine();

            Console.WriteLine("每个更新间隔发生的第 0 代 GC 次数:");
            LogSumCounterPayload(obj.Gen0GcCount);
            Console.WriteLine();

            Console.WriteLine("第 0 代 GC 的字节数:");
            LogMeanCounterPayload(obj.Gen0GcSize);
            Console.WriteLine();

            Console.WriteLine("每个更新间隔发生的第 1 代 GC 次数:");
            LogSumCounterPayload(obj.Gen1GcCount);
            Console.WriteLine();

            Console.WriteLine("第 1 代 GC 的字节数:");
            LogMeanCounterPayload(obj.Gen1GcSize);
            Console.WriteLine();

            Console.WriteLine("每个更新间隔发生的第 2 代 GC 次数:");
            LogSumCounterPayload(obj.Gen2GcCount);
            Console.WriteLine();

            Console.WriteLine("第 2 代 GC 的字节数:");
            LogMeanCounterPayload(obj.Gen2GcSize);
            Console.WriteLine();

            Console.WriteLine("大型对象堆的字节数:");
            LogMeanCounterPayload(obj.LOHSize);
            Console.WriteLine();

            Console.WriteLine("已固定对象堆的字节数:");
            LogMeanCounterPayload(obj.POHSize);
            Console.WriteLine();

            Console.WriteLine("GC 堆碎片:");
            LogMeanCounterPayload(obj.GcFragmentation);
            Console.WriteLine();

            Console.WriteLine("尝试锁定监视器时出现争用的次数:");
            LogSumCounterPayload(obj.MonitorLockContentionCount);
            Console.WriteLine();

            Console.WriteLine("当前活动的 Timer 实例的计数:");
            LogMeanCounterPayload(obj.ActiveTimerCount);
            Console.WriteLine();

            Console.WriteLine(" 在某个时间点加载到进程中的 Assembly 实例的计数:");
            LogMeanCounterPayload(obj.AssemblyCount);
            Console.WriteLine();

            Console.WriteLine("迄今为止 ThreadPool 中已处理的工作项数:");
            LogSumCounterPayload(obj.ThreadPoolCompletedTimesCount);
            Console.WriteLine();

            Console.WriteLine("ThreadPool 中当前已加入处理队列的工作项数:");
            LogMeanCounterPayload(obj.ThreadPoolQueueLength);
            Console.WriteLine();

            Console.WriteLine("ThreadPool 中当前存在的线程池线程数:");
            LogMeanCounterPayload(obj.ThreadPoolThreadCount);
            Console.WriteLine();

            Console.WriteLine("某个时间点映射到进程上下文的物理内存量:");
            LogMeanCounterPayload(obj.WorkingSet);
            Console.WriteLine();

            Console.WriteLine(" JIT 编译的 IL 的总大小:");
            LogMeanCounterPayload(obj.ILBytesJitted);
            Console.WriteLine();

            Console.WriteLine(" JIT 编译的方法数:");
            LogMeanCounterPayload(obj.MethodJittedCount);
            Console.WriteLine();

            Console.WriteLine(" 由 GC 所提交的字节数:");
            LogSumCounterPayload(obj.GcCommittedBytes);
            Console.WriteLine();

            Console.WriteLine($"==================end={DateTime.Now}==================");
            Console.WriteLine();
        }
        ***/

        private static void LogSumCounterPayload(SumCounterPayload sumCounterPayload, EventWrittenEventArgs eventData)
        {
            if (sumCounterPayload == null) return;
            System.Console.WriteLine($"{DateTime.Now.ToLongTimeString()}=>名称【{sumCounterPayload.Name}】显示名称【{sumCounterPayload.DisplayName}】 显示速率【{sumCounterPayload.DisplayRateTimeScale}】" +
                $"增量【{sumCounterPayload.Increment}】 间隔时间(秒)【{sumCounterPayload.IntervalSec}】 计数器类型【{sumCounterPayload.CounterType}】 " +
                $"元数据【{sumCounterPayload.Metadata}】 显示单位【{sumCounterPayload.DisplayUnits}】");
        }

        private static void LogMeanCounterPayload(MeanCounterPayload meanCounterPayload, EventWrittenEventArgs eventData)
        {
            if (meanCounterPayload == null) return;
            System.Console.WriteLine($"{ DateTime.Now.ToLongTimeString()}=>名称【{ meanCounterPayload.Name}】 显示名称【{meanCounterPayload.DisplayName}】 平均值【{meanCounterPayload.Mean}】 " +
                $"标准差【{meanCounterPayload.StandardDeviation}】 计数【{meanCounterPayload.Count}】最小值【{meanCounterPayload.Min}】 最大值【{meanCounterPayload.Max}】 " +
                $"间隔时间(秒)【{meanCounterPayload.IntervalSec}】 系列【{meanCounterPayload.Series}】 计数器类型【{meanCounterPayload.CounterType}】 " +
                $"元数据【{meanCounterPayload.Metadata}】 显示单位【{meanCounterPayload.DisplayUnits}】");
        }
    }
}
